package com.immediatus.graphics.vertex;

import com.immediatus.engine.util.Transformation;
import com.immediatus.util.FastFloatBuffer;

public class RectangleBatchVertexBuffer extends VertexBuffer {
	public static final int VERTICES_PER_RECTANGLE = 6;

	private int _index;

	public RectangleBatchVertexBuffer(final int capacity_, final int drawType_, final boolean managed_) {
		super(capacity_ * 2 * VERTICES_PER_RECTANGLE, drawType_, managed_);
	}

	public int getIndex() {
		return this._index;
	}

	public void setIndex(final int index_) {
		this._index = index_;
	}

	public void add(final float x_, final float y_, final float w_, final float h_, final float rotation_) {
		final float widthHalf = w_ * 0.5f;
		final float heightHalf = h_ * 0.5f;

        Transformation transformation = new Transformation();
        transformation.setToIdentity();
        transformation.postTranslate(-widthHalf, -heightHalf);
        transformation.postRotate(rotation_);
        transformation.postTranslate(widthHalf, heightHalf);
        transformation.postTranslate(x_, y_);
		this.add(w_, h_, transformation);
	}

	public void add(final float x_, final float y_, final float w_, final float h_, final float scaleX_, final float scaleY_) {
		final float widthHalf = w_ * 0.5f;
		final float heightHalf = h_ * 0.5f;

        Transformation transformation = new Transformation();
        transformation.setToIdentity();
        transformation.postTranslate(-widthHalf, -heightHalf);
        transformation.postScale(scaleX_, scaleY_);
        transformation.postTranslate(widthHalf, heightHalf);
        transformation.postTranslate(x_, y_);
		
		this.add(w_, h_, transformation);
	}

	public void add(final float x_, final float y_, final float w_, final float h_, final float rotation_, final float scaleX_, final float scaleY_) {
		final float widthHalf = w_ * 0.5f;
		final float heightHalf = h_ * 0.5f;

        Transformation transformation = new Transformation();
        transformation.setToIdentity();
        transformation.postTranslate(-widthHalf, -heightHalf);
        transformation.postScale(scaleX_, scaleY_);
        transformation.postRotate(rotation_);
        transformation.postTranslate(widthHalf, heightHalf);
        transformation.postTranslate(x_, y_);
		
		this.add(w_, h_, transformation);
	}

	public void add(final float w_, final float h_, final Transformation transformation_) {

        final float[] verticles = new float[8];
        verticles[0] = 0;
        verticles[1] = 0;
        verticles[2] = 0;
        verticles[3] = h_;
        verticles[4] = w_;
        verticles[5] = 0;
        verticles[6] = w_;
        verticles[7] = h_;

        transformation_.transform(verticles);

		this.addInner(verticles[0], verticles[1], verticles[2], verticles[3],  verticles[4], verticles[5], verticles[6], verticles[7]);
	}

	public void add(final float x_, final float y_, final float w_, final float h_) {
		this.addInner(x_, y_, x_ + w_, y_ + h_);
	}

	public void addInner(final float x1_, final float y1_, final float x2_, final float y2_) {
		final int x1 = Float.floatToRawIntBits(x1_);
		final int y1 = Float.floatToRawIntBits(y1_);
		final int x2 = Float.floatToRawIntBits(x2_);
		final int y2 = Float.floatToRawIntBits(y2_);

		final int[] bufferData = this._BufferData;
		int index = this._index;
		bufferData[index++] = x1;
		bufferData[index++] = y1;
		bufferData[index++] = x1;
		bufferData[index++] = y2;
		bufferData[index++] = x2;
		bufferData[index++] = y1;
		bufferData[index++] = x2;
		bufferData[index++] = y1;
		bufferData[index++] = x1;
		bufferData[index++] = y2;
		bufferData[index++] = x2;
		bufferData[index++] = y2;
		this._index = index;
	}

	public void addInner(final float x1_, final float y1_, final float x2_, final float y2_, final float x3_, final float y3_, final float x4_, final float y4_) {
		final int x1 = Float.floatToRawIntBits(x1_);
		final int y1 = Float.floatToRawIntBits(y1_);
		final int x2 = Float.floatToRawIntBits(x2_);
		final int y2 = Float.floatToRawIntBits(y2_);
		final int x3 = Float.floatToRawIntBits(x3_);
		final int y3 = Float.floatToRawIntBits(y3_);
		final int x4 = Float.floatToRawIntBits(x4_);
		final int y4 = Float.floatToRawIntBits(y4_);

		final int[] bufferData = this._BufferData;
		int index = this._index;
		bufferData[index++] = x1;
		bufferData[index++] = y1;
		bufferData[index++] = x2;
		bufferData[index++] = y2;
		bufferData[index++] = x3;
		bufferData[index++] = y3;
		bufferData[index++] = x3;
		bufferData[index++] = y3;
		bufferData[index++] = x2;
		bufferData[index++] = y2;
		bufferData[index++] = x4;
		bufferData[index++] = y4;
		this._index = index;
	}

	public void submit() {
		final FastFloatBuffer buffer = this._FloatBuffer;
		buffer.position(0);
		buffer.put(this._BufferData);
		buffer.position(0);

		super.setHardwareBufferNeedsUpdate();
	}
}
